﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Markup;
using Windows.UI;
using Windows8Accelerator.Core.Xaml.Controls.RichText;
using Windows8Accelerator.Core.Xaml.Converters;
using Windows8Accelerator.Core.Xaml.Helpers;
using Windows8Accelerator.Core.Xaml.Html;

namespace Windows8Accelerator.Core.Xaml.Controls
{
    public class RichTextHtmlSourcePlaceHolder : Block { }


    [TemplatePart(Name = "richTextBlock", Type = typeof(RichTextBox))]
    [ContentProperty("Blocks")]
    public class SuperRichTextBlock : Control
    {
        private RichTextBox _RichTextBlock;

        public bool RemoveLastColumn
        {
            get { return (bool)GetValue(RemoveLastColumnProperty); }
            set { SetValue(RemoveLastColumnProperty, value); }
        }
        public static readonly DependencyProperty RemoveLastColumnProperty =
            DependencyProperty.Register("RemoveLastColumn", typeof(bool), typeof(SuperRichTextBlock), new PropertyMetadata(false));

        private RichTextBlockHtmlLoader _RichTextBlockHtmlLoader = new RichTextBlockHtmlLoader();
        public RichTextBlockHtmlLoader RichTextBlockHtmlLoader
        {
            get
            {
                return _RichTextBlockHtmlLoader;
            }
        }

        public SuperRichTextBlock()
        {
            DefaultStyleKey = typeof(SuperRichTextBlock);
            Blocks = new ObservableCollection<Block>();
            Blocks.CollectionChanged += Blocks_CollectionChanged;
            _RichTextBlockHtmlLoader.HyperlinkClick += _RichTextBlockHtmlLoader_HyperlinkClick;
            _RichTextBlockHtmlLoader.ImageClick += _RichTextBlockHtmlLoader_ImageClick;
            SizeChanged += SuperRichTextBlock_SizeChanged;
        }

        void SuperRichTextBlock_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            UpdateInternalColumnWidth();
        }

        public ICommand ImageClickCommand
        {
            get { return (ICommand)GetValue(ImageClickCommandProperty); }
            set { SetValue(ImageClickCommandProperty, value); }
        }
        public static readonly DependencyProperty ImageClickCommandProperty =
            DependencyProperty.Register("ImageClickCommand", typeof(ICommand), typeof(SuperRichTextBlock), new PropertyMetadata(null));

        public ICommand HyperlinkClickCommand
        {
            get { return (ICommand)GetValue(HyperlinkClickCommandProperty); }
            set { SetValue(HyperlinkClickCommandProperty, value); }
        }
        public static readonly DependencyProperty HyperlinkClickCommandProperty =
            DependencyProperty.Register("HyperlinkClickCommand", typeof(ICommand), typeof(SuperRichTextBlock), new PropertyMetadata(null));

        public event EventHandler<ImageClickEventArgs> ImageClick;
        void _RichTextBlockHtmlLoader_ImageClick(object sender, ImageClickEventArgs e)
        {
            if (ImageClickCommand != null)
                ImageClickCommand.Execute(e);
            if (ImageClick != null)
                ImageClick(this, e);
        }

        public event EventHandler<HyperlinkClickEventArgs> HyperlinkClick;
        void _RichTextBlockHtmlLoader_HyperlinkClick(object sender, HyperlinkClickEventArgs e)
        {
            if (HyperlinkClickCommand != null)
                HyperlinkClickCommand.Execute(e);
            if (HyperlinkClick != null)
                HyperlinkClick(this, e);
        }

        public override void OnApplyTemplate()
        {
            //_RichTextColumns = GetTemplateChild("richTextColumns") as RichTextColumns;
            _RichTextBlock = GetTemplateChild("richTextBlock") as RichTextBox;
            UpdateInternalColumnWidth(); 
            if (_RichTextBlock != null)
            {
                foreach (var item in Blocks)
                {
                    _RichTextBlock.Blocks.Add(item);
                }
            }
            LoadHtml(HtmlSource);
        }

        void Blocks_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            if (_RichTextBlock != null)
            {
                if (e.NewItems != null)
                {
                    foreach (Block item in e.NewItems)
                    {
                        _RichTextBlock.Blocks.Add(item);
                    }
                }
                if (e.OldItems != null)
                {
                    foreach (Block item in e.OldItems)
                    {
                        if (_RichTextBlock.Blocks.Contains(item))
                            _RichTextBlock.Blocks.Remove(item);
                    }
                }
            }
        }

        public ObservableCollection<Block> Blocks
        {
            get { return (ObservableCollection<Block>)GetValue(BlocksProperty); }
            private set { SetValue(BlocksProperty, value); }
        }
        public static readonly DependencyProperty BlocksProperty =
            DependencyProperty.Register("Blocks", typeof(ObservableCollection<Block>), typeof(SuperRichTextBlock), new PropertyMetadata(new ObservableCollection<Block>()));

        public bool IsTextSelectionEnabled
        {
            get { return (bool)GetValue(IsTextSelectionEnabledProperty); }
            set { SetValue(IsTextSelectionEnabledProperty, value); }
        }
        public static readonly DependencyProperty IsTextSelectionEnabledProperty =
            DependencyProperty.Register("IsTextSelectionEnabled", typeof(bool), typeof(SuperRichTextBlock), new PropertyMetadata(false));

        public Thickness ColumnMargin
        {
            get { return (Thickness)GetValue(ColumnMarginProperty); }
            set { SetValue(ColumnMarginProperty, value); }
        }
        public static readonly DependencyProperty ColumnMarginProperty =
            DependencyProperty.Register("ColumnMargin", typeof(Thickness), typeof(SuperRichTextBlock), new PropertyMetadata(new Thickness(80,0,0,0)));

        public double ColumnWidth
        {
            get { return (double)GetValue(ColumnWidthProperty); }
            set { SetValue(ColumnWidthProperty, value); }
        }
        public static readonly DependencyProperty ColumnWidthProperty =
            DependencyProperty.Register("ColumnWidth", typeof(double), typeof(SuperRichTextBlock), new PropertyMetadata((double)560, ColumnWidthPropertyChanged));

        private static void ColumnWidthPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
        {
            if (e.NewValue is string)
                ((SuperRichTextBlock)d).ColumnWidth = double.Parse((string)e.NewValue, CultureInfo.InvariantCulture);
            else
                ((SuperRichTextBlock)d).UpdateInternalColumnWidth();
        }

        private void UpdateInternalColumnWidth()
        {
            if (ColumnWidth < 0)
                InternalColumnWidth = ActualWidth;
            else
                InternalColumnWidth = ColumnWidth;
        }

        public string HtmlSource
        {
            get { return (string)GetValue(HtmlSourceProperty); }
            set 
            { 
                SetValue(HtmlSourceProperty, value); 
            }
        }
        public static readonly DependencyProperty HtmlSourceProperty =
            DependencyProperty.Register("HtmlSource", typeof(string), typeof(SuperRichTextBlock), new PropertyMetadata("", HtmlSourcePropertyChangedCallback));

        public double InternalColumnWidth
        {
            get { return (double)GetValue(InternalColumnWidthProperty); }
            set { SetValue(InternalColumnWidthProperty, value); }
        }
        public static readonly DependencyProperty InternalColumnWidthProperty =
            DependencyProperty.Register("InternalColumnWidth", typeof(double), typeof(SuperRichTextBlock), new PropertyMetadata((double)0));
       
        private static void HtmlSourcePropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue is string)
            {
                ((SuperRichTextBlock)d).LoadHtml(e.NewValue as string);
            }
        }

        private List<Block> _OriginalBlocks;

        private void LoadHtml(string html)
        {
            if (_RichTextBlock != null && !string.IsNullOrEmpty(html))
            {
                if (_OriginalBlocks == null)
                {
                    _OriginalBlocks = new List<Block>();
                    foreach (var block in Blocks)
                    {
                        _OriginalBlocks.Add(block);
                    }
                }
                else
                {
                    foreach (var block in _RichTextBlock.Blocks.ToList())
                    {
                        if (!_OriginalBlocks.Contains(block))
                            _RichTextBlock.Blocks.Remove(block);
                    }                
                }
                _RichTextBlockHtmlLoader.LoadAsync(_RichTextBlock, html);
            }
        }
    }
}
